/*
 * @Description:游戏启动面板
 * @Author: maskMan
 * @LastEditTime: 2024-10-21 09:44:48
 */
import CacheStore from '../general/cacheStore'
import { gameList, MARK } from '../define/variable'
import audioManager from '../general/audioManager'
import Config from '../general/config'
import { GameStatis } from '../general/gameStatis'
import Resource from '../general/resManager'
import { helpOpen, openGameStatis, openScore, playEffect, tipsTime } from '../general/shorts'
import { util } from '../general/util'
import Hall from './hall'
const { ccclass, property } = cc._decorator
@ccclass
export default class GamePanel extends cc.Component {
  @property(cc.Node)
  game_node: cc.Node = null
  @property(cc.Node)
  startNode: cc.Node = null
  @property(cc.Node)
  titleNode: cc.Node = null
  @property(cc.Label)
  maxScoreStr: cc.Label = null
  @property(cc.Label)
  currScoreStr: cc.Label = null
  @property(cc.Label)
  currMaxScoreStr: cc.Label = null
  @property(cc.Node)
  startPanel: cc.Node = null
  /**本实例 */
  static instance: GamePanel
  isDone: boolean = false
  rotaAction: cc.ActionInterval = null
  gamePath: IGamePath
  gameScore: IUserScore
  isGameOver = false
  currGameSc: cc.Component
  audioList: IAudio = {
    score: 0,
    fail: 0,
    lose: 0,
    win: 0
  }
  private _isRuning = false
  currEndSc: GameStatis = null
  onLoad() {
    this.gamePath = gameList.find((v) => v.gamePack == Config.gamePack)
    GamePanel.instance = this
    this._btnAction()
    this._setInitData()
  }
  /**设置初始化数据 */
  private _setInitData() {
    try {
      for (const k in this.audioList) {
        this.audioList[k] = util.getRandomInt(1, 5)
      }
      this.currMaxScoreStr.node.parent.active = false
      this.currScoreStr.node.parent.active = false
      let record = CacheStore.getPublicData('maxRecord')
      if (record) {
        this.maxScoreStr.string = record.toString()
      } else {
        this.maxScoreStr.string = '0'
      }
    } catch (error) {
      console.log('error: ', error)
    }
  }
  //按钮动作
  private _btnAction() {
    try {
      this.startPanel.active = true
      this.startNode.stopAllActions()
      this.titleNode.stopAllActions()
      const ac1 = cc.scaleTo(0.5, 0.8, 0.8).easing(cc.easeBackIn())
      const ac2 = cc.scaleTo(0.5, 0.9, 0.9).easing(cc.easeBounceOut())
      const ac4 = cc.scaleTo(2, 1, 1).easing(cc.easeBounceOut())
      const ac3 = cc.delayTime(3)
      const seq = cc.sequence(ac1, ac2).repeat(2)
      this.startNode.runAction(cc.sequence(seq, ac4, ac3).repeatForever())
      const ac5 = cc.scaleTo(6, 0.9)
      const ac6 = cc.scaleTo(12, 1.2).easing(cc.easeBounceOut())
      this.titleNode.runAction(cc.repeatForever(cc.sequence(ac5, ac6)))
    } catch (error) {
      console.log('error: ', error)
    }
  }
  //播放音效
  private _playEffect(audioName: 'score' | 'fail' | 'lose' | 'win') {
    try {
      Resource.loadRes<cc.AudioClip>(`/effect/${audioName}${this.audioList[audioName]}`, cc.AudioClip).then((pre) => {
        if (pre) {
          audioManager.playEffect(pre)
        }
      })
    } catch (error) {
      console.log('error: ', error)
    }
  }
  /**时间转换 */
  private _changeTime(timeValue: number): string {
    const time = 3600 * 1000
    const h = Math.floor(timeValue / time)
    const m = Math.floor((timeValue % time) / 60000)
    const s = Math.floor(((timeValue % time) % 60000) / 1000)
    return `${h}时${m}分${s}秒`
  }
  /**创建得分记录 */
  private _createScore(): IUserScore {
    try {
      const user = Hall.instance.gameInstance.user
      let record = CacheStore.getPublicData('maxRecord')
      if (record) {
        record = Number(record)
      }
      const score: IUserScore = {
        uid: user?.uid || null,
        gamePath: `games/${Config.gamePack}`,
        startTime: util.now(),
        trainTime: null,
        score: 0,
        maxScore: 0,
        maxRecord: record || 0,
        checkResult: null
      }
      return score
    } catch (error) {
      console.log('error: ', error)
    }
  }
  onOpenHelp() {
    if (this._isRuning) {
      return false
    }
    this._isRuning = true
    this.scheduleOnce(() => {
      this._isRuning = false
    }, 1)
    helpOpen(this.gamePath)
  }
  //关闭界面
  onCloseGame() {
    const rootNode = this.node
    cc.director.getPhysicsManager().enabled = false
    cc.director.getCollisionManager().enabled = false
    playEffect('close')
    if (this.currGameSc && this.gameScore) {
      this.gameScore.trainTime = util.now() - this.gameScore.startTime
    }
    Hall.instance.gameInstance.createUserScore(this.gameScore)
    if (this.currGameSc && this.currGameSc['mp4']) {
      rootNode.destroy()
    } else {
      rootNode.runAction(
        cc.sequence(
          cc.moveTo(0.4, 0, 750).easing(cc.easeBackIn()),
          cc.callFunc(() => {
            rootNode.destroy()
          })
        )
      )
    }
  }
  onDestroy() {
    this.node.emit(MARK.NODE_EVENT, true)
  }
  /**开始游戏 */
  async onStartGame() {
    try {
      if (this._isRuning) {
        return false
      }
      this._isRuning = true
      this.scheduleOnce(() => {
        this._isRuning = false
      }, 1)
      const ret = await Resource.loadRes(`games/${Config.gamePack}/${Config.gamePack}`)
      if (ret) {
        playEffect('shui')
        await this.destroyGame()
        /**创建得分 */
        this.startPanel.active = false
        this.gameScore = this._createScore()
        this.isGameOver = false
        const pre = cc.instantiate(ret)
        const scName = this.gamePath.gamePack
        const sc = pre.getComponent(`${scName}`)
        this.game_node.addChild(pre)
        this.currGameSc = sc
        this.currMaxScoreStr.node.parent.active = true
        this.currScoreStr.node.parent.active = true
        this.currScoreStr.string = '0'
        this.currMaxScoreStr.string = '0'
        this.maxScoreStr.string = this.gameScore.maxRecord.toString()
        GamePanel.instance.currEndSc = null
        this.hideTitle(pre)
        pre.on(MARK.NODE_EVENT, (res: boolean) => {
          if (res) {
            this.currGameSc = null
            this.gameScore = null
            this.isGameOver = false
            this._setInitData()
            this._btnAction()
          }
        })
        return
      }
      tipsTime('加载资源错误', 3)
    } catch (error) {
      console.log('加载资源错误')
    }
  }
  //游戏销毁
  public destroyGame(show?: true): Promise<boolean> {
    try {
      return new Promise((resolve) => {
        console.log(this.currGameSc)
        if (cc.isValid(this.currGameSc?.node)) {
          this.currGameSc.node.destroy()
          this.currGameSc = null
        }
        this.gameScore = null
        this.isGameOver = false
        this.currEndSc = null
        this.startPanel.active = true
        this.currMaxScoreStr.node.parent.active = false
        this.currScoreStr.node.parent.active = false
        playEffect('btn')
        return resolve(true)
      })
    } catch (error) {
      console.log('游戏销毁错误')
    }
  }
  //更新得分
  public updateScore(score) {
    try {
      if (this.isGameOver == true) {
        return
      }
      openScore(score)
      if (score > 0) {
        this._playEffect('score')
      } else {
        this._playEffect('fail')
      }
      this.gameScore.score += score
      this.currScoreStr.string = this.gameScore.score.toString()
      if (this.gameScore.score > this.gameScore.maxScore) {
        this.gameScore.maxScore = this.gameScore.score
        this.currMaxScoreStr.string = this.gameScore.maxScore.toString()
        if (this.gameScore.maxScore > this.gameScore.maxRecord) {
          this.gameScore.maxRecord = this.gameScore.maxScore
          this.maxScoreStr.string = this.gameScore.maxRecord.toString()
          CacheStore.setPublicData('maxRecord', this.gameScore.maxRecord)
        }
      }
    } catch (error) {
      console.log('得分错误')
    }
  }
  //更新测训结果
  public updateCheckResult(result) {
    try {
      if (this.isGameOver == true) {
        return
      }
      this.gameScore.checkResult = result
    } catch (error) {
      console.log('error: ', error)
    }
  }
  //训练结束界面
  public showGameStatis(show?: boolean) {
    if (!show) {
      openScore(-1)
    }
    this._playEffect('win')
    this.gameScore.trainTime = util.now() - this.gameScore.startTime
    Hall.instance.gameInstance.createUserScore(this.gameScore)
    const costTime = `训练时长: ${this._changeTime(this.gameScore.trainTime)}`
    const score = `本次得分: ${this.gameScore.score}`
    const maxScore = `最高得分: ${this.gameScore.maxScore}`
    const scoreData = {
      costTime,
      score,
      maxScore,
      otherData: ''
    }
    openGameStatis(scoreData)
  }
  /**隐藏标题 */
  public hideTitle(_node: cc.Node) {
    if (cc.find('bg/title', _node)) {
      cc.find('bg/title', _node).active = false
    }
  }
}
